package com.xls.aclservice.service.impl;

import cn.hutool.core.convert.Convert;
import com.xls.aclservice.entity.SysRole;
import com.xls.aclservice.entity.SysUserRole;
import com.xls.aclservice.service.SysUserRoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xls.base.exception.BusinessException;
import com.xls.aclservice.entity.SysRoleMenu;
import com.xls.aclservice.mapper.SysRoleMapper;
import com.xls.aclservice.service.SysRoleMenuService;
import com.xls.aclservice.service.SysRoleService;
import com.xls.aclservice.vo.RoleQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xls
 * @since 2021-03-23
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Override
    public Page<SysRole> getRolePage(Integer page, Integer limit, RoleQuery roleQuery) {
        QueryWrapper<SysRole> roleQueryWrapper = new QueryWrapper<>();
        String name = roleQuery.getName();
        String description = roleQuery.getDescription();
        Boolean status = roleQuery.getStatus();
        String begin = roleQuery.getBegin();
        String end = roleQuery.getEnd();
        roleQueryWrapper.likeRight(!StringUtils.isEmpty(name), "name", name)
                .likeRight(!StringUtils.isEmpty(description), "description", description)
                .eq(!StringUtils.isEmpty(status), "status", status)
                .gt(!StringUtils.isEmpty(begin), "gmt_create", begin)
                .lt(!StringUtils.isEmpty(end), "gmt_create", end)
                .eq("is_deleted", 0)
                .orderByAsc("sort");
        return this.page(new Page<>(page, limit), roleQueryWrapper);
    }

    @Override
    @Transactional
    public void updateStatus(SysRole sysRole) {
        SysRole oldSysRole = this.getById(sysRole.getId());
        if (oldSysRole.getStatus() != sysRole.getStatus()) {
            sysRoleMapper.update(new SysRole(), new UpdateWrapper<SysRole>()
                    .eq("id", sysRole.getId())
                    .set("status", sysRole.getStatus()));
        } else {
            throw new BusinessException(999, "此用户已被他人修改哦!");
        }
    }

    /**
     * 保存角色并且设置角色菜单
     *
     * @param sysRole
     */
    @Override
    @Transactional
    public void saveRole(SysRole sysRole) {
        this.saveOrUpdate(sysRole);
        setRoleMenu(sysRole);
    }

    /**
     * 批量插入角色菜单关联表
     *
     * @param sysRole
     */
    @Transactional
    public void setRoleMenu(SysRole sysRole) {
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", sysRole.getId()));
        List<SysRoleMenu> sysRoleMenuList = new ArrayList<>();
        String[] menuIds = sysRole.getRoutes();
        for (String menuId : menuIds) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(sysRole.getId());
            sysRoleMenu.setMenuId(Convert.toLong(menuId));
            sysRoleMenuList.add(sysRoleMenu);
        }
        sysRoleMenuService.saveBatch(sysRoleMenuList);
    }

    @Override
    public SysRole getRole(Long id) {
        SysRole sysRole = sysRoleMapper.selectById(id);
        List<Long> menuIds = sysRoleMenuService.list(new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getDeleted, 0)
                .eq(SysRoleMenu::getRoleId, id)
                .select(SysRoleMenu::getMenuId))
                .stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
        sysRole.setRoutes(Convert.toStrArray(menuIds));
        return sysRole;
    }

    /**
     * 删除角色
     * @param id
     */
    @Override
    @Transactional
    public void removeRole(String id) {
        this.removeById(id);
        removeRoleMenu(id);
    }

    /**
     * 删除角色菜单关联表
     * @param id
     */
    private void removeRoleMenu(String id) {
        sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
    }

    @Override
    public List<SysRole> selectRoleByUserId(Long id) {
        List<SysUserRole> sysUserRoleList = sysUserRoleService.list(new QueryWrapper<SysUserRole>().eq("user_id", id).select("role_id"));
        List<Long> roleIdList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
        List<SysRole> sysRoleList = new ArrayList<>();
        if(roleIdList.size() > 0) {
            sysRoleList = baseMapper.selectBatchIds(roleIdList);
        }
        return sysRoleList;
    }

}
